﻿using System.Linq;
using CID.Domain.Audit;
using CID.Web.Controllers;
using CID.Web.Models.Audit;
using NailsFramework.IoC;
using NailsFramework.Persistence;
using NailsFramework.UserInterface.TestingSupport;
using NUnit.Framework;

namespace CID.Web.Tests.Controllers
{
    [TestFixture]
    class DeploymentLogControllerTests : BaseWebTests
    {
        [Inject]
        public IBag<ReleaseDeploymentLog> ReleaseDeploymentLogs { private get; set; }
        private DeploymentLogController controller;

        public override void SetUp()
        {
            base.SetUp();
            controller = TestControllers.Get<DeploymentLogController>();
        }

        [Test]
        public void TestIndex_NoFilter_ShouldGetAllReleaseDeploymentLogAndReturnDefaultView()
        {
            var result = controller.Index();

            Assert.IsNotNull(result);
            Assert.AreEqual("", result.ViewName);
            Assert.IsInstanceOf<ReleaseDeploymentLogListViewModel>(result.Model);
            var filteredReleaseDeploymentLogs = ((ReleaseDeploymentLogListViewModel)result.Model).ReleaseDeploymentLogs.ToArray();
            CollectionAssert.AreEquivalent(ReleaseDeploymentLogs, filteredReleaseDeploymentLogs);
        }

        [Test]
        public void TestIndex_FilterByRelease_ShouldGetAllReleaseDeploymentLogForThatReleaseAndReturnDefaultView()
        {
            var releaseId = ReleaseDeploymentLogs.First().Release.Id;
            var result = controller.Index(releaseId: releaseId);

            Assert.IsNotNull(result);
            Assert.AreEqual("", result.ViewName);
            Assert.IsInstanceOf<ReleaseDeploymentLogListViewModel>(result.Model);
            var filteredReleaseDeploymentLogs = ((ReleaseDeploymentLogListViewModel)result.Model).ReleaseDeploymentLogs.ToArray();
            CollectionAssert.AreEquivalent(new int[] { releaseId }, filteredReleaseDeploymentLogs.Select(x => x.Release.Id).Distinct());
            CollectionAssert.AreEquivalent(ReleaseDeploymentLogs.Where(x => x.Release.Id == releaseId).ToArray() , filteredReleaseDeploymentLogs);
        }

        [Test]
        public void TestIndex_FilterByEnvironment_ShouldGetAllReleaseDeploymentLogForThatEnvironmentAndReturnDefaultView()
        {
            var environmentId = ReleaseDeploymentLogs.First().Environment.Id;
            var result = controller.Index(environmentId: environmentId);

            Assert.IsNotNull(result);
            Assert.AreEqual("", result.ViewName);
            Assert.IsInstanceOf<ReleaseDeploymentLogListViewModel>(result.Model);
            var filteredReleaseDeploymentLogs = ((ReleaseDeploymentLogListViewModel)result.Model).ReleaseDeploymentLogs.ToArray();
            CollectionAssert.AreEquivalent(new int[] { environmentId }, filteredReleaseDeploymentLogs.Select(x => x.Environment.Id).Distinct());
            CollectionAssert.AreEquivalent(ReleaseDeploymentLogs.Where(x => x.Environment.Id == environmentId).ToArray(), filteredReleaseDeploymentLogs);
        }

        [Test]
        public void TestIndex_FilterByResponsible_ShouldGetAllReleaseDeploymentLogForThatResponsibleAndReturnDefaultView()
        {
            var responsibleId = ReleaseDeploymentLogs.First().Responsible.Id;
            var result = controller.Index(responsibleId: responsibleId);

            Assert.IsNotNull(result);
            Assert.AreEqual("", result.ViewName);
            Assert.IsInstanceOf<ReleaseDeploymentLogListViewModel>(result.Model);
            var filteredReleaseDeploymentLogs = ((ReleaseDeploymentLogListViewModel)result.Model).ReleaseDeploymentLogs.ToArray();
            CollectionAssert.AreEquivalent(new int[] { responsibleId }, filteredReleaseDeploymentLogs.Select(x => x.Responsible.Id).Distinct());
            CollectionAssert.AreEquivalent(ReleaseDeploymentLogs.Where(x => x.Responsible.Id == responsibleId).ToArray(), filteredReleaseDeploymentLogs);
        }

        [Test]
        public void TestIndex_FilterByStatus_ShouldGetAllReleaseDeploymentLogForThatStatusAndReturnDefaultView()
        {
            var status = ReleaseDeploymentLogs.First().Status;
            var result = controller.Index(status: status);

            Assert.IsNotNull(result);
            Assert.AreEqual("", result.ViewName);
            Assert.IsInstanceOf<ReleaseDeploymentLogListViewModel>(result.Model);
            var filteredReleaseDeploymentLogs = ((ReleaseDeploymentLogListViewModel)result.Model).ReleaseDeploymentLogs.ToArray();
            CollectionAssert.AreEquivalent(new DeploymentStatus[] { status }, filteredReleaseDeploymentLogs.Select(x => x.Status).Distinct());
            CollectionAssert.AreEquivalent(ReleaseDeploymentLogs.Where(x => x.Status == status).ToArray(), filteredReleaseDeploymentLogs);
        }

        [Test]
        public void TestDetails_ShouldReturnDefaultViewWithEntity()
        {
            var model = ReleaseDeploymentLogs.First();

            var result = controller.Details(model.Id);

            Assert.IsNotNull(result);
            Assert.AreEqual("", result.ViewName);
            Assert.IsInstanceOf<ReleaseDeploymentLog>(result.Model);
            Assert.AreEqual(model.Id, ((ReleaseDeploymentLog)result.Model).Id);
        }
    }
}
